/* $RCSFile: CachedPortalModuleControl.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/UI/WebControls/CachedPortalModuleControl.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:29  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Reflection;
using System.ComponentModel;
using System.Configuration;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;

using AddonNice.Diagnostics;
using AddonNice.UI;
using AddonNice.UI.WebControls;
using AddonNice.Security;
using AddonNice.Configuration;

using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.UI.WebControls
{
	/// <summary>
	/// The CachedPortalModuleControl class is a custom server control that
	/// the Portal framework uses to optionally enable output caching of 
	/// individual portal module's content.<br />
	/// If a CacheTime value greater than 0 seconds is specified within the 
	/// Portal.Config configuration file, then the CachePortalModuleControl
	/// will automatically capture the output of the Portal Module User Control
	/// it wraps. It will then store this captured output within the ASP.NET
	/// Cache API. On subsequent requests (either by the same browser -- or
	/// by other browsers visiting the same portal page), the CachedPortalModuleControl
	/// will attempt to resolve the cached output out of the cache.
	/// </summary>
	/// <remarks>
	/// In the event that previously cached output can't be found in the
	/// ASP.NET Cache, the CachedPortalModuleControl will automatically instatiate
	/// the appropriate portal module user control and place it within the
	/// portal page.
	/// </remarks>
	public class CachedPortalModuleControl : Control 
	{
		// Private field variables
		private ModuleConfiguration  _moduleConfiguration;
		private string          _cachedOutput = string.Empty;
		private int             _portalID = 0;

		/// <summary>
		/// ModuleBaseConfiguration
		/// </summary>
		public ModuleConfiguration ModuleConfiguration 
		{
			get 
			{
				return _moduleConfiguration;
			}
			set 
			{
				_moduleConfiguration = value;
			}
		}

		/// <summary>
		/// ModuleID
		/// </summary>
		public int ModuleID 
		{
			get 
			{
				return _moduleConfiguration.ModuleID;
			}
		}

		/// <summary>
		/// PortalID
		/// </summary>
		public int PortalID 
		{

			get 
			{
				return _portalID;
			}
			set 
			{
				_portalID = value;
			}
		}

		/// <summary>
		/// The CacheKey property is used to calculate a "unique" cache key
		/// entry to be used to store/retrieve the portal module's content
		/// from the ASP.NET Cache.
		/// </summary>
		public string CacheKey 
		{
			get 
			{
				// changes to Language behaviour require addition of culture names to cache key
				PortalSettings portalSettings = (PortalSettings) HttpContext.Current.Items[StStr.strPortalSettings];
				StringBuilder sb = new StringBuilder();
				sb.Append("adn_");
				sb.Append(portalSettings.BaseAlias.ToLower());
				sb.Append("_mid");
				sb.Append(ModuleID.ToString());
				sb.Append("[");
				sb.Append(portalSettings.PortalContentLanguage);
				sb.Append("+"); 
				sb.Append(portalSettings.PortalUILanguage); 
				sb.Append("+");
				sb.Append(portalSettings.PortalDataFormattingCulture); 
				sb.Append("]");

				return sb.ToString();
			}
		}

		/// <summary>
		/// The CreateChildControls method is called when the ASP.NET Page Framework
		/// determines that it is time to instantiate a server control.<br/>
		/// The CachedPortalModuleControl control overrides this method and attempts
		/// to resolve any previously cached output of the portal module from the ASP.NET cache.  
		/// If it doesn't find cached output from a previous request, then the
		/// CachedPortalModuleControl will instantiate and add the portal module's
		/// User Control instance into the page tree.
		/// </summary>
		protected override void CreateChildControls() 
		{
			// Attempt to resolve previously cached content from the ASP.NET Cache
			if (_moduleConfiguration.CacheTime > 0) 
			{
				_cachedOutput = (string) Context.Cache[CacheKey];
			}

			// If no cached content is found, then instantiate and add the portal
			// module user control into the portal's page server control tree
			if (_cachedOutput == null) 
			{
				base.CreateChildControls();
                try
                {
                    if ( ModuleTraceSwitch.Sw.TraceVerbose )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"CachedPortalModuleControl CreateChildControls LoadControl : {0}.", _moduleConfiguration.DesktopSrc),ModuleTraceSwitch.Sw.Info);
                    string controlPath          =   _moduleConfiguration.DesktopSrc;
                    PortalModuleControl pm      =   ((ADNPage)Page).LoadPortalModule(controlPath,PortalID,ModuleConfiguration,false);
                    Controls.Add(pm);
                }
                catch (Exception ex3)
                {
                    if ( ModuleTraceSwitch.Sw.TraceInfo )
                        Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"CachedPortalModuleControl CreateChildControls ex: {0}", ex3),ModuleTraceSwitch.Sw.Info);
                    throw;
                }
			}
		}

		/// <summary>
		/// The Render method is called when the ASP.NET Page Framework
		/// determines that it is time to render content into the page output stream.
		/// The CachedPortalModuleControl control overrides this method and captures
		/// the output generated by the portal module user control. It then 
		/// adds this content into the ASP.NET Cache for future requests.
		/// </summary>
		protected override void Render(HtmlTextWriter output) 
		{
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"CachedPortalModuleControl Render BEG CacheTime: {0}",_moduleConfiguration.CacheTime),ModuleTraceSwitch.Sw.Info);
			// If no caching is specified, render the child tree and return 
			if (_moduleConfiguration.CacheTime <= 0) 
			{
				base.Render(output);
                if ( ModuleTraceSwitch.Sw.TraceVerbose )
                    Trace2.WriteLine( "CachedPortalModuleControl Render END .",ModuleTraceSwitch.Sw.Info);
				return;
			}

			// If no cached output was found from a previous request, render
			// child controls into a TextWriter, and then cache the results
			// in the ASP.NET Cache for future requests.
			if (_cachedOutput == null) 
			{
				using (TextWriter tempWriter = new StringWriter())
				{
					base.Render(new HtmlTextWriter(tempWriter));
					_cachedOutput = tempWriter.ToString();
				}

				// Cache added file dependencies for cache insert
				if ( _moduleConfiguration.CacheDependency != null)
				{
					string[] dependencyList = new string[this._moduleConfiguration.CacheDependency.Count];
					int i = 0;
					foreach(string thisfile in this._moduleConfiguration.CacheDependency)
					{
						dependencyList[i] = thisfile;
						i++;
					}
					using (CacheDependency _cacheDependency = new CacheDependency(dependencyList))
					{
						Context.Cache.Insert(CacheKey, _cachedOutput, _cacheDependency, DateTime.Now.AddSeconds(_moduleConfiguration.CacheTime), TimeSpan.Zero);
					}
				}
				else
				{
					Context.Cache.Insert(CacheKey, _cachedOutput, null, DateTime.Now.AddSeconds(_moduleConfiguration.CacheTime), TimeSpan.Zero);
				}

			}

			// Output the user control's content
			output.Write(_cachedOutput);
		}
	}
}
